package com.wmada.spring.bean;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.timerchina.toolkit.security.SecurityService;
import com.timerchina.toolkit.time.TimeUtils;
import com.wmada.spring.validate.ValidPassword;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.validator.constraints.Length;

import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Positive;
import java.io.Serializable;
import java.util.Date;

/**
 * @author will.ma
 * @date 2020-2-2
 */
@Data
@DynamicUpdate
@NoArgsConstructor
@Entity
public class User implements Serializable {

    @Positive
    @Id
    @GeneratedValue
    private Long id;

    @NotBlank
    @Length(min = 4, max = 32)
    @Column(nullable = false, unique = true)
    private String username;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    @ValidPassword
    @Transient
    private String password;

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    @Column
    private String salt;

    @JsonIgnore
    @Column(name = "password")
    private String signedPassword;

    @Column
    private String name;

    @Column
    private String nickname;

    @Email
    @Column
    private String email;

    @Column
    private String phone;

    @Column(nullable = false, updatable = false)
    private Date registerTime = TimeUtils.now();

    @Column
    private Date lastLoginTime;

    @Column
    private Date lockTillTime;

    @Column(nullable = false)
    private Integer failureTimes = 0;

    @Column(nullable = false)
    private Integer isDelete = 0;

    public User(String nickname, String email, String username, Date registerTime) {
        super();
        this.email = email;
        this.nickname = nickname;
        this.username = username;
        this.registerTime = registerTime;
    }

    public boolean valid(String password) {
        return SecurityService.validate(password, salt, signedPassword);
    }

    public void resetPassword(String password) {
        this.password = password;
        this.salt = generateSalt();
        this.signedPassword = signPassword(password, salt);
    }

    public static String generateSalt() {
        return SecurityService.generateSalt();
    }

    public static String signPassword(String password, String salt) {
        return SecurityService.sign(password, salt);
    }

}